package nautilus.moneykeeper.fragment;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import nautilus.moneykeeper.MainBaseSlidingActvity;
import nautilus.moneykeeper.R;
import nautilus.moneykeeper.adapter.SpinnerNamedAdapter;
import nautilus.moneykeeper.dao.AccountDAO;
import nautilus.moneykeeper.dto.Account;
import nautilus.moneykeeper.dto.AccountType;
import nautilus.moneykeeper.dto.CurrencyUnit;
import nautilus.moneykeeper.system.Constant;
import nautilus.moneykeeper.system.SystemConfig;
import nautilus.moneykeeper.utilities.TaskExecuter;

import android.app.Dialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class UpdateAccountFragment extends AbstractMainContentFragment{
	
	public static final String TAG = "UpdateAccountFragment";
	
	public static final int MSG_LOAD_DATA_DONE = 1;
	public static final int MSG_LOAD_DATA_ERROR = -1;
	
	private EditText txtAccNumber, txtAccName;
	private EditText txtDateTime;
	private EditText txtBalance;
	private Spinner spinnerAccType, spinnerUnit;
	private EditText txtDescription;
	private Account updatingAccount = null;
	private Dialog dlgConfirmOut;
	
	private SpinnerNamedAdapter<AccountType> adapterAccType = null;
	private SpinnerNamedAdapter<CurrencyUnit> adapterCurrencyUnit = null;
	
	private SimpleDateFormat _format = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
	
	/*data*/
	private ArrayList<AccountType> lstCT = null;
	private ArrayList<CurrencyUnit> lstUnit = null;
	
	private Handler _handler = new Handler(new Handler.Callback() {
		
		@Override
		public boolean handleMessage(Message msg) {
			switch(msg.what){
				case MSG_LOAD_DATA_DONE:
					_handler.removeMessages(MSG_LOAD_DATA_DONE);
					bindData();
				break;
			}
			return false;
		}
	});
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedState){
		View view = inflater.inflate(R.layout.account, parent, false);
		txtAccNumber = (EditText)view.findViewById(R.id.edit_account_number);
		txtAccName = (EditText)view.findViewById(R.id.edit_account_name);
		txtBalance = (EditText)view.findViewById(R.id.edit_account_amount);
		txtDescription = (EditText)view.findViewById(R.id.edit_account_description);
		txtDateTime = (EditText)view.findViewById(R.id.edit_account_openned_date);
		spinnerAccType = (Spinner)view.findViewById(R.id.edit_account_spinner_type);
		spinnerUnit = (Spinner)view.findViewById(R.id.edit_account_spinner_unit);
		initListeners();
		TaskExecuter.getInstance(getActivity()).execute(new LoadListDataTask());
		return view;
	}
	
	private void initListeners(){
		spinnerAccType.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
				
				
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub
			}
		});
		
	}
	
	class LoadListDataTask implements Runnable{
		public void run(){
			AccountDAO dao = new AccountDAO(UpdateAccountFragment.this.getActivity());
			lstCT = dao.getAllAccountTypes();
			AccountType addCT = new AccountType(0, "Add new account type");
			lstCT.add(addCT);
			
			lstUnit = dao.getAllCurrencyUnits();
			
			dao.close();
			_handler.sendEmptyMessage(MSG_LOAD_DATA_DONE);
		}
	}
	
	private void bindData(){
		if(adapterAccType==null){
			adapterAccType = new SpinnerNamedAdapter<AccountType>(getActivity(), lstCT);
			adapterCurrencyUnit = new SpinnerNamedAdapter<CurrencyUnit>(getActivity(), lstUnit);
			spinnerAccType.setAdapter(adapterAccType);
			spinnerUnit.setAdapter(adapterCurrencyUnit);
		}else{
			adapterAccType.refreshData(lstCT);
			adapterCurrencyUnit.refreshData(lstUnit);
		}
		
		Date now = new Date();
		String strDate = _format.format(now);
		if(getArguments() != null){
			updatingAccount = (Account)getArguments().getSerializable(Constant.EXTRA_ACCOUNT);
			if(updatingAccount != null){
				strDate = _format.format(updatingAccount.getDateTime());
				txtAccNumber.setText(updatingAccount.getNumber());
				txtAccName.setText(updatingAccount.getName());
				txtBalance.setText(""+updatingAccount.getBalance());
				txtDescription.setText(updatingAccount.getDescription());
				
				for(int i=0;i<adapterCurrencyUnit.getCount();i++)
					if(adapterCurrencyUnit.getItemId(i)==updatingAccount.getCurrencyUnit().getId()){
						spinnerUnit.setSelection(i);
						break;
					}
				
				for(int i=0;i<adapterAccType.getCount();i++)
					if(adapterAccType.getItemId(i)==updatingAccount.getType().getId()){
						spinnerAccType.setSelection(i);
						break;
					}
			}
		}
		txtDateTime.setText(strDate);
	}
	
	private boolean onSaveClicked(){
		if(updatingAccount == null){
			return addNewAccount();
		}
		
		return updateCurrentAccount();
	}
	
	private boolean updateCurrentAccount(){
		AccountDAO dao = null;
		long balance = Long.parseLong(txtBalance.getText().toString());
		String des = txtDescription.getText().toString();
		try {
			updatingAccount.setName(txtAccName.getText().toString());
			updatingAccount.setNumber(txtAccNumber.getText().toString());
			updatingAccount.setDateTime(_format.parse(txtDateTime.getText().toString()));
			updatingAccount.setType((AccountType)spinnerAccType.getSelectedItem());
			updatingAccount.setCurrencyUnit((CurrencyUnit)spinnerUnit.getSelectedItem());
			updatingAccount.setBalance(balance);
			updatingAccount.setDescription(des);
			dao = new AccountDAO(getActivity());
			dao.updateAccount(updatingAccount);
			return true;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}finally{
			if(dao != null)
				dao.close();
		}
	}
	
	private boolean addNewAccount(){
		String accName = txtAccName.getText().toString();
		long balance = Long.parseLong(txtBalance.getText().toString());
		String des = txtDescription.getText().toString();
		AccountDAO dao = null;
		try {
			Date openedTime = _format.parse(txtDateTime.getText().toString());
			AccountType acctype = (AccountType)spinnerAccType.getSelectedItem();
			CurrencyUnit unit = (CurrencyUnit)spinnerUnit.getSelectedItem();
			Account account = new Account();
			account.setNumber(txtAccNumber.getText().toString());
			account.setDateTime(openedTime);
			account.setName(accName);
			account.setType(acctype);
			account.setCurrencyUnit(unit);
			account.setBalance(balance);
			account.setDescription(des);
			dao = new AccountDAO(getActivity());
			dao.addAccount(account);
			return true;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}finally{
			if(dao != null)
				dao.close();
		}
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
			case R.id.edit_account_openned_date:
				showDatetimePicker();
				break;
				
			case R.id.btn_account_save:
				if(txtAccName.getText().toString().length() <=0){
					Toast.makeText(getActivity(), "Account name cannot be blank.", 
							Toast.LENGTH_LONG).show();
					return;
				}
				
				if(txtBalance.getText().toString().length()<=0){
					Toast.makeText(getActivity(), "You must initialize balance of this account.", 
							Toast.LENGTH_LONG).show();
					return;
				}
				
				if(onSaveClicked())
					showConfirmOutDialog();
				break;
				
			case R.id.btn_home_menu_slide:
				((MainBaseSlidingActvity)getActivity()).toggle();
			break;
		}
	}
	
	
	private void showConfirmOutDialog(){
		final Dialog dialog = new Dialog(getActivity());
		dialog.setContentView(R.layout.confirm_dialog);
		TextView text = (TextView) dialog.findViewById(R.id.dlg_text);
		
		String question = "Account saved successfully.\nDo you want to add a new account?";
		if(updatingAccount != null)
			question = "Update account successfully.\nDo you want to add a new account?";
		
		text.setText(question);
		Button btnYes = (Button) dialog.findViewById(R.id.dlg_btn_yes);
		btnYes.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				updatingAccount = null;
				txtAccName.setText("");
				txtAccNumber.setText("");
				txtBalance.setText("0");
				txtDateTime.setText( (new Date()).toString() );
				txtDescription.setText("");
				dialog.dismiss();
			}
		});
		
		Button btnNo = (Button) dialog.findViewById(R.id.dlg_btn_no);
		btnNo.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.dismiss();
				onBackPressed();
			}
		});
		dialog.show();
	}
	
	private void showDatetimePicker(){
		// custom dialog
		final Dialog dialog = new Dialog(getActivity());
		dialog.setContentView(R.layout.date_time_picker);
		dialog.setTitle("Choose date time");
		 
		// set the custom dialog components - text, image and button
//		TextView text = (TextView) dialog.findViewById(R.id.text);
//		text.setText("Android custom dialog example!");
//		ImageView image = (ImageView) dialog.findViewById(R.id.image);
//		image.setImageResource(R.drawable.ic_launcher);
//		 
//		Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
//		// if button is clicked, close the custom dialog
//		dialogButton.setOnClickListener(new OnClickListener() {
//			@Override
//			public void onClick(View v) {
//				dialog.dismiss();
//			}
//		});
		 
		dialog.show();
	}

	@Override
	public void onBackPressed() {
		Bundle arg = null;
		if(updatingAccount!=null){
			arg = new Bundle();
			arg.putSerializable(Constant.EXTRA_ACCOUNT, updatingAccount);
		}
		
		((MainBaseSlidingActvity)getActivity()).postBackPressed(arg);
	}
}
